package cn.lix.sc.rpc.server.service.impl;

import cn.lix.sc.rpc.impl.common.annotations.RpcService;
import cn.lix.sc.rpc.service.demo.service.EnhancedFileService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 增强文件处理服务实现，支持多种内容类型和文件流处理
 * @author lix
 * @date 2024
 */
@RpcService(
    value = "enhancedFileService",
    contentTypes = {
        RpcService.ContentType.JSON,
        RpcService.ContentType.MULTIPART,
        RpcService.ContentType.OCTET_STREAM,
        RpcService.ContentType.TEXT_PLAIN
    },
    enableStreaming = true
)
@Service
public class EnhancedFileServiceImpl implements EnhancedFileService {

    private final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(this.getClass());

    @Override
    public String uploadFile(MultipartFile file, String description) {
        try {
            log.info("接收文件上传: 文件名={}, 大小={} bytes, 描述={}", 
                file.getOriginalFilename(), file.getSize(), description);
            
            // 模拟文件处理
            String fileName = file.getOriginalFilename();
            String contentType = file.getContentType();
            long size = file.getSize();
            
            // 这里可以添加实际的文件存储逻辑
            // Files.copy(file.getInputStream(), targetPath);
            
            return String.format("文件上传成功: %s (%s, %d bytes), 描述: %s", 
                fileName, contentType, size, description);
                
        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败: " + e.getMessage());
        }
    }

    @Override
    public byte[] downloadFile(String fileName) {
        try {
            log.info("请求下载文件: {}", fileName);
            
            // 模拟文件读取
            // 这里应该从实际存储位置读取文件
            // Path filePath = Paths.get("uploads", fileName);
            // return Files.readAllBytes(filePath);
            
            // 模拟返回文件内容
            String content = "这是模拟的文件内容: " + fileName + "\n生成时间: " + System.currentTimeMillis();
            return content.getBytes("UTF-8");
            
        } catch (Exception e) {
            log.error("文件下载失败", e);
            throw new RuntimeException("文件下载失败: " + e.getMessage());
        }
    }

    @Override
    public byte[] processStream(InputStream inputStream, String operation) {
        try {
            log.info("处理输入流, 操作类型: {}", operation);
            
            // 读取输入流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                baos.write(buffer, 0, bytesRead);
            }
            
            byte[] inputData = baos.toByteArray();
            log.info("读取到数据: {} bytes", inputData.length);
            
            // 根据操作类型处理数据
            switch (operation.toLowerCase()) {
                case "reverse":
                    return reverseBytes(inputData);
                case "compress":
                    return compressData(inputData);
                case "encrypt":
                    return encryptData(inputData);
                default:
                    return inputData; // 原样返回
            }
            
        } catch (IOException e) {
            log.error("流处理失败", e);
            throw new RuntimeException("流处理失败: " + e.getMessage());
        }
    }

    @Override
    public String processText(String content) {
        log.info("处理文本内容, 长度: {} 字符", content.length());
        
        // 简单的文本处理示例
        String processed = content
            .toUpperCase()
            .replaceAll("\\s+", "_")
            .concat("_PROCESSED_" + System.currentTimeMillis());
            
        return "处理结果: " + processed;
    }

    @Override
    public byte[] processImage(byte[] imageData, String operation) {
        log.info("处理图片数据, 大小: {} bytes, 操作: {}", imageData.length, operation);
        
        // 模拟图片处理
        switch (operation.toLowerCase()) {
            case "resize":
                return resizeImage(imageData);
            case "rotate":
                return rotateImage(imageData);
            case "compress":
                return compressImage(imageData);
            default:
                return imageData;
        }
    }

    @Override
    public String batchProcessFiles(String files, String batchOperation) {
        log.info("批量处理文件, 操作: {}, 文件列表: {}", batchOperation, files);
        
        // 模拟批量处理
        int processedCount = ThreadLocalRandom.current().nextInt(1, 10);
        int failedCount = ThreadLocalRandom.current().nextInt(0, 3);
        
        return String.format("批量处理完成: 操作=%s, 成功=%d, 失败=%d", 
            batchOperation, processedCount, failedCount);
    }

    // 辅助方法
    private byte[] reverseBytes(byte[] data) {
        byte[] reversed = new byte[data.length];
        for (int i = 0; i < data.length; i++) {
            reversed[i] = data[data.length - 1 - i];
        }
        return reversed;
    }

    private byte[] compressData(byte[] data) {
        // 模拟压缩（实际应该使用GZIP或其他压缩算法）
        log.info("模拟数据压缩: {} -> {} bytes", data.length, data.length / 2);
        byte[] compressed = new byte[data.length / 2];
        System.arraycopy(data, 0, compressed, 0, compressed.length);
        return compressed;
    }

    private byte[] encryptData(byte[] data) {
        // 模拟简单加密（异或操作）
        byte[] encrypted = new byte[data.length];
        byte key = (byte) 0xAA;
        for (int i = 0; i < data.length; i++) {
            encrypted[i] = (byte) (data[i] ^ key);
        }
        return encrypted;
    }

    private byte[] resizeImage(byte[] imageData) {
        // 模拟图片缩放
        log.info("模拟图片缩放");
        return imageData; // 实际应该使用图片处理库
    }

    private byte[] rotateImage(byte[] imageData) {
        // 模拟图片旋转
        log.info("模拟图片旋转");
        return imageData; // 实际应该使用图片处理库
    }

    private byte[] compressImage(byte[] imageData) {
        // 模拟图片压缩
        log.info("模拟图片压缩");
        return imageData; // 实际应该使用图片处理库
    }
} 